using System;
using System.Text;
using System.IO;

// .NET 4.0: in System.Runtime.Serialization.dll 
// .NET 3.5: in System.ServiceModel.Web.dll
using System.Runtime.Serialization.Json;


namespace SharpObjects.Utils
{

    public class JsonSerialization
    {
        public static string Serialize<T>(T obj, params Type[] knownTypes)
        {
            MemoryStream memoryStream = new MemoryStream();

            Serialize<T>(obj, memoryStream, knownTypes);

            string serialized = Encoding.Default.GetString(memoryStream.ToArray());
            return serialized;
        }

        public static void Serialize<T>(T obj, Stream stream, params Type[] knownTypes)
        {
            Type type = typeof (T);
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(type, knownTypes);
            serializer.WriteObject(stream, obj);
        }

        public static T Deserialize<T>(string json, params Type[] knownTypes)
        {
            using (MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(json)))
            {
                T obj = Deserialize<T>(memoryStream, knownTypes);
                return obj;
            }
        }

        public static T Deserialize<T>(Stream stream, params Type[] knownTypes)
        {
            T obj;
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), knownTypes);
            obj = (T)serializer.ReadObject(stream);
            return obj;
        }

        public static T[] DeserializeToArray<T>(string json, params Type[] knownTypes)
        {
            using (MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(json)))
            {
                T[] objs = DeserializeToArray<T>(memoryStream, knownTypes);
                return objs;
            }
        }

        public static T[] DeserializeToArray<T>(Stream stream, params Type[] knownTypes)
        {
            T[] objs;
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T[]), knownTypes);
            objs = (T[]) serializer.ReadObject(stream);
            return objs;
        }
    }
}